package jalgebrava.group.groups;

import jalgebrava.group.Group;
import jalgebrava.group.GroupElement;
import jalgebrava.util.collections.ImmutableIterable;
import jalgebrava.util.collections.ImmutableIterator;

public class FreeStringGroupFactory {
	@SuppressWarnings("unused") // just there to keep EMMA happy
	private final static FreeStringGroupFactory instance = new FreeStringGroupFactory();
	private FreeStringGroupFactory() {
		// hidden
	}
	
	private static final Group<String> THE_FREE_STRING_GROUP = new Group<String>("FREE") {

		private char reverseCase(char c) {
			if (Character.isLowerCase(c)) {
				return Character.toUpperCase(c);
			}
			return Character.toLowerCase(c);
		}
		@Override
		public boolean contains(String x) {
			for (int i=0;i<x.length();i++) {
				char c = x.charAt(i);
				if (Character.isLetter(c)) {
					return false;
				}
			}
			for (int i=0;i<x.length() - 1 ; i++) {
				if (Character.isLetter(x.charAt(i))) {
					return false;
				}
				if (x.charAt(i) == x.charAt(i+1)) {
					
				}
			}
			return true;
		}

		@Override
		public ImmutableIterable<GroupElement<String>> elements() {
			throw new RuntimeException("infinite group");
		}

		@Override
		public String inv(String x) {
			StringBuilder sb = new StringBuilder();
			for (int i=0;i<x.length();i++) {
				char c = x.charAt(i);
				sb.append(reverseCase(c));
			}
			return sb.reverse().toString();
		}

		@Override
		public String mul(String x, String y) {
			if (x.length() == 0) {
				return y;
			}
			if (y.length() == 0) {
				return x;
			}
			if (x.charAt(x.length()-1) == reverseCase(y.charAt(0))) {
				return mul(x.substring(0,x.length()-1) , y.substring(1));
			}
			return x + y;
			
		}

		@Override
		public ImmutableIterator<String> iterator() {
			throw new RuntimeException("infinite group");
		}

		@Override
		public String toShortString(String g) {
			return g;
		}

		@Override
		public String unit() {
			return "";
		}

		@Override
		public boolean equals(String x, String y) {
			return x.equals(y);
		}

		@Override
		public int hashCode(String x) {
			return x.hashCode();
		}

		@Override
		public String toString(String x) {
			return x; // for now, is ugly
		}

		@Override
		public int size() {
			throw new RuntimeException("infinite group");
		}
		
	};
	
	final static Group<String> mk() {
		return THE_FREE_STRING_GROUP;
	}
}
